package com.naiterui.ehp.bs.ds.modules.security.service;

import com.naiterui.common.redis.RedisUtil;
import com.naiterui.ehp.bp.constants.CommonConstant;
import com.naiterui.ehp.bp.security.exception.BadRequestException;
import com.naiterui.ehp.bp.security.service.IPermissionService;
import com.naiterui.ehp.bp.security.utils.SecurityUtils;
import com.naiterui.ehp.bp.utils.encypt.GengerCode;
import com.naiterui.ehp.bp.utils.lang.StringUtil;
import com.naiterui.ehp.bs.ds.common.utils.JwtUser;
import com.naiterui.ehp.bs.ds.common.utils.SMSUtil;
import com.naiterui.ehp.bs.ds.common.utils.SMSUtil.Template;
import com.naiterui.ehp.bs.ds.modules.sys.entity.User;
import com.naiterui.ehp.bs.ds.modules.sys.mapper.UserMapper;
import com.naiterui.ehp.bs.ds.modules.sys.service.IUserService;
import java.util.Arrays;
import java.util.Set;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

@AllArgsConstructor
@Slf4j
@Service(IPermissionService.SERVICE_NAME)
public class PermissionServiceImpl implements IPermissionService {

  private final IUserService userService;
  private final UserMapper userMapper;

  @Override
  public Boolean check(String... permissions) {
    JwtUser jwtUser = SecurityUtils.getCurrentUser();
    Set<String> permission = this.userService.getPermission(jwtUser.getId());
    return jwtUser.isAdmin() || Arrays.stream(permissions).anyMatch(permission::contains);
  }


  @Override
  public String sendSmsCode(String username) throws BadRequestException {
    if (StringUtils.isBlank(username)) {
      throw new BadRequestException("用户名为空");
    }
    // 查询用户信息
    User user = this.userMapper.findByUsername(username);
    if (user == null) {
      throw new BadRequestException("用户不存在");
    }
    if (!StringUtil.isMobileNum(user.getMobile())) {
      throw new BadRequestException("用户手机号不正确");
    }

    String smsSendKey = this.getSmsSendKey(user.getMobile());
    String smsSendTimeKey = this.getSmsSendTimeKey(user.getMobile());
    if (RedisUtil.keyOps().existsKey(smsSendTimeKey)) {
      log.info("验证码发送过于频繁，请稍后再试,电话为phoneNum=" + user.getMobile());
      throw new BadRequestException("验证码发送过于频繁，请稍后再试!(" + StringUtil.securePhone(user.getMobile()) + ")");
    }

    // 验证码发送10分钟内不变更验证码
    String smsCode = RedisUtil.valueOps().getString(smsSendKey);
    if (StringUtils.isBlank(smsCode)) {
      smsCode = GengerCode.generateSmsCode();
    }

    SMSUtil.sendSMS(user.getMobile(), Template.USER_LOGIN_SMS_CDOE, smsCode);

    // 上次发送验证码的时间
    RedisUtil.valueOps().set(smsSendTimeKey, smsCode, 60);
    // 验证码存放10分钟
    RedisUtil.valueOps().set(smsSendKey, smsCode, 10 * 60);

    return "短信已发送至" + StringUtil.securePhone(user.getMobile()) + "，请注意查收";
  }

  @Override
  public void verifySmsCode(String username, String smsCode) {
    if (StringUtils.isAnyBlank(username, smsCode)) {
      throw new BadRequestException("用户手机号不正确");
    }
    // 登录必存在用户信息，不校验
    User user = this.userMapper.findByUsername(username);
    if (!StringUtil.isMobileNum(user.getMobile())) {
      throw new BadRequestException("用户手机号不正确");
    }

    String smsSendKey = this.getSmsSendKey(user.getMobile());
    String smsCodeCache = RedisUtil.valueOps().getString(smsSendKey);
    if (StringUtils.equals(smsCode, smsCodeCache)) {
      RedisUtil.keyOps().delete(smsSendKey);
    } else {
      throw new BadRequestException("验证码不正确，请确认后再试");
    }
  }

  private String getSmsSendKey(String phone) {
    return CommonConstant.REDIS_PRE_DS + "login_send_" + phone;
  }

  private String getSmsSendTimeKey(String phone) {
    return CommonConstant.REDIS_PRE_DS + "login_send_time_" + phone;
  }
}
